/***************************************************************
*Defines for the lines used to communicate with the TTS module
*are listed below. There are data direction (TRIS) settings
*under spi_setup that need to be changed if these are moved.
****************************************************************/#define TTS_RESET PORTCbits.RC0 // connects to X5-1#define TTS_MISO PORTCbits.RC4 // connects to X5-2#define TTS_notSS PORTCbits.RC1 // connects to X5-3#define TTS_SCLK PORTCbits.RC3 // connects to X5-4#define TTS_RnotB PORTCbits.RC2 // connects to X5-5#define TTS_MOSI PORTCbits.RC5 // connects to X5-6#define TTS_INT PORTCbits.RC6 // connects to X5-7#include <p18f452.h>#include <string.h>#include <ctype.h>#include <stdlib.h>#include <delay.h>//Function prototypesvoid tts_setup (void);void spi_setup(void);void tts_reset(void);char SPI_comm(char sendChar);void tts_send_command(char* command,char* output);void tts_send_string(char* command,char* output);void get_weight_line(int weight,char* unit,char* output);void tts_wait(void);void speak(char* outstring);char tts_is_ready(void);//Stringsstaticunsignedchar _status[]={0x04,0x00,0xFF};// Request Status command.staticunsignedchar _status_long[]={0x04,0x00,0x00,0x00,0xFF};// Request long Status.staticunsignedchar _set_clock[]={0x14,0x00,0xFF};// Set Clock command.staticunsignedchar _power_up[]={0x02,0x00,0xFF};// PowerUp command.staticunsignedchar _set_vol[]={0x51,0x00,0xFF};// Set volume register at maximum command.staticunsignedchar _set_int[]={0x4E,0x20,0xFF};// Enable conversion interrup command.staticunsignedchar _clr_int[]={0x06,0x00,0x00,0x00,0xFF};// Clear interrupt flags command.staticunsignedchar _data[]="Welcome to Cassia Scales.";// Welcome Message.staticunsignedchar _stop[]={0x4B,0x00,0xFF};// Stop conversion command./**
* A public array to store a string for the TTS unit.
*/staticunsignedchar _say_str[64];/**
* A public array to store responses from the TTS unit.
*/staticunsignedchar outbuff[64];/**
*Initialises the master-side hardware for SPI communication with the TTS unit.
*@see tts_setup()
*/void spi_setup(void){
TRISCbits.TRISC5=0;//SDO is output
TRISCbits.TRISC3=0;//SCK is output
TRISCbits.TRISC4=1;//SDO is input
TRISCbits.TRISC1=0;//RC1 (notSS) is output
TRISCbits.TRISC0=0;//RC0 (Reset) is output
TRISCbits.TRISC2=1;//RC0 (RnotB) is input// TRISCbits.TRISC6 = 1; //RC1 (Interrupt) is input (NO LONGER USED)
SSPCON1bits.CKP=1;//clock idle is high.
SSPSTATbits.CKE=1;
SSPCON1bits.SSPM3=0;//Set clock speed as
SSPCON1bits.SSPM2=0;//Fosc/64
SSPCON1bits.SSPM1=1;//
SSPCON1bits.SSPM0=0;//
SSPSTATbits.SMP=1;// Sample at end of data output.
SSPCON1bits.SSPEN=1;// Enable SPI}/**
*Initialises the slave-side TTS unit.
*@see spi_setup()
*/void tts_setup (void){
tts_reset();
tts_send_command(_status,outbuff);if((outbuff[0]==0x00)&&(outbuff[1]==0x80)){
tts_send_command(_set_clock,outbuff);// send set clock command.
tts_send_command(_status,outbuff);// send status request command.
tts_send_command(_power_up,outbuff);// send powerup command.
tts_wait();// wait for powerup.
tts_send_command(_status,outbuff);// send status request command.}if((outbuff[0]==0x04)&&(outbuff[1]==0x80)){
tts_reset();// If TTS chip has status 0x0480, reset will bring it into// ready status 0x0580.}while(!((outbuff[0]==0x05)&&(outbuff[1]==0x80))){
tts_reset();
tts_send_command(_status,outbuff);}if((outbuff[0]&0x04)&&(outbuff[1]==0x80)){
tts_send_command(_set_vol,outbuff);// send volume command.
tts_wait();}
tts_send_command(_status_long,outbuff);while(outbuff[2]|outbuff[3]){// waiting for converion buffer to
tts_send_command(_status_long,outbuff);// be empty.}
tts_send_command(_set_int,outbuff);// Sending enable conversion completed// interrupts.
tts_send_command(_clr_int,outbuff);// Clearing interrupt flags.
tts_send_string(_data,outbuff);// Sending welcome message.}/**
*Generates a text string in the format "%d %s",weight,unit eg. "346 grams"
*@param weight an integer weight
*@param unit a pointer to a string containing the name of the desired unit.
*@param output a pointer to an output string.
*/void get_weight_line(int weight,char* unit,char* output){char count =0;itoa(weight,output);// Converts weight to a null terminated string.while(output[count])// Finds the end of the weight string.
count++;
output[count]=' ';// Replaces the \0 character with a space.
count++;strcpy(&output[count],unit);// Appends the units string to the weight string.}/**
*Calls a delay function.
*/void tts_wait(void){
Delay1KTCYx(10);}/**
*Resets the TTS module by setting the RESET line for longer than 0.5 micro seconds.
*/void tts_reset(void){
TTS_RESET =1;
tts_wait();
TTS_RESET =0;}/**
*Sends a command to the TTS chip over the SPI communications module.
*The SS' line is pulled low before the transmission and then raised
*after the transmission is complete.
*Commands passed to this function must be terminated with a '0xFF' character
*as 0x00 is a frequently used opcode character for the TTS chip.
*@param command a pointer to a string containing the command to be sent.
*@param output a pointer to a buffer to hold the recieved output.
*@see tts_send_string()
*/void tts_send_command(char* command,char* output){char count =0;
TTS_notSS =0;//START TRANSMISSIONwhile(command[count]!=0xFF)//Send the command string until 0xFF{
output[count]= SPI_comm(command[count]);
count++;}
TTS_notSS =1;//END TRANSMISSION
output[count]=0xFF;//Place 0xFF at the end of the recieve buffer//for debugging.}/**
*Sends a string to be spoken to the TTS chip over the SPI communications module.
*The SS' line is pulled low before the transmission and then raised
*after the transmission is complete.
*The function prefixes the string with the 'convert' command - 0x8100 and
*appends it with the termination character 0x1a.
*@param command a pointer to a null terminated string to be spoken.
*@param output a pointer to a buffer to hold the recieved output.
*@see tts_send_command()
*/void tts_send_string(char* command,char* output){char count =0;
TTS_notSS =0;//START TRANSMISSION
output[0]= SPI_comm(0x81);// Send conversion command.
output[1]= SPI_comm(0x00);while(command[count]!=0x00)// Send string until 0x00.{
output[count+2]= SPI_comm(command[count]);
count++;}
output[count]= SPI_comm(0x1a);// Send termination character.
TTS_notSS =1;//END TRANSMISSION
output[count]=0xFF;//Place 0xFF at the end of the recieve buffer//for debugging.}/**
*Performs 1 complete 8-bit SPI transaction by sending one character
*and receiving one character.
*A timeout counter is implemented that resets the TTS module if the
*R/B' line is not active within reasonable time.
*@param sendChar a character to be transmitted
*@return feedback character recieved from SPI communication.
*@see tts_send_command(),tts_send_string()
*/char SPI_comm(char sendChar){int counter =0;while(!TTS_RnotB)// Test the Ready/notBusy line.{
counter++;// Increment the timeout counter.if(counter ==0){
tts_reset();// If timeout counter overflows,return0;// reset the TTS unit and exit.}}
SSPBUF = sendChar;// Write the character to the SPI buffer.while(!SSPSTATbits.BF){//wait until reception is complete.}return SSPBUF;// Read feedback character from SPI buffer.}/**
*A public wrapper function to simplify speech functionality.
*Clears any interrupt flags, stops any active conversions
*and then transmits the desired string to the TTS chip.
*@param outstring an ASCII string to be spoken.
*@see tts_is_ready()
*/void speak (char* outstring){
tts_send_command(_clr_int,outbuff);// Clear interrupt flags.
tts_send_command(_stop,outbuff);// Stop active conversion.
tts_send_string(outstring, outbuff);// Send new string.}/**
*Checks the status bits received from the tts unit to see if
*the 'conversion complete' flag has been set.
*@return logical status of the ICNV status bit.
*/char tts_is_ready(void){
tts_send_command(_status,outbuff);// Request a status.if(outbuff[0]&0x20)// Check ICNV status bit.return1;elsereturn0;}